import scala.collection.mutable
import scala.util.Random

object SchoolInformationSystem extends App {
  // 1. 数据结构定义
  case class Student(
                      id: String,
                      name: String,
                      className: String,
                      age: Int,
                      gender: String
                    )

  case class Course(
                     id: String,
                     name: String,
                     teacherId: String,
                     credit: Double,
                     maxStudents: Int
                   )

  case class Score(
                    studentId: String,
                    courseId: String,
                    score: Double,
                    examDate: String
                  )

  case class Teacher(
                      id: String,
                      name: String,
                      department: String,
                      title: String
                    )

  // 2. 数据存储
  private val students = mutable.Map[String, Student]()
  private val courses = mutable.Map[String, Course]()
  private val scores = mutable.ListBuffer[Score]()
  private val teachers = mutable.Map[String, Teacher]()

  // 3. 辅助函数：生成ID
  private def generateId(prefix: String): String =
    s"$prefix${System.currentTimeMillis()}"

  // 4. 学生管理模块函数
  def addStudent(name: String, className: String, age: Int, gender: String): String = {
    val id = generateId("S")
    students(id) = Student(id, name, className, age, gender)
    id
  }

  def getStudent(studentId: String): Option[Student] = students.get(studentId)

  def getStudentsByClass(className: String): List[Student] =
    students.values.filter(_.className == className).toList

  def countStudentsByGender(gender: String): Int =
    students.values.count(_.gender == gender)

  // 5. 课程管理模块函数
  def addCourse(name: String, teacherId: String, credit: Double, maxStudents: Int): String = {
    val id = generateId("C")
    courses(id) = Course(id, name, teacherId, credit, maxStudents)
    id
  }

  def getCourse(courseId: String): Option[Course] = courses.get(courseId)

  def getCoursesByTeacher(teacherId: String): List[Course] =
    courses.values.filter(_.teacherId == teacherId).toList

  // 6. 成绩管理模块函数
  def addScore(studentId: String, courseId: String, score: Double, examDate: String): Boolean = {
    // 验证学生和课程是否存在
    if (students.contains(studentId) && courses.contains(courseId)) {
      scores += Score(studentId, courseId, score, examDate)
      true
    } else {
      false
    }
  }

  def getStudentScores(studentId: String): List[Score] =
    scores.filter(_.studentId == studentId).toList

  def getCourseScores(courseId: String): List[Score] =
    scores.filter(_.courseId == courseId).toList

  // 高阶函数：统计课程成绩
  def analyzeCourseScores(
                           courseId: String,
                           analyzer: List[Double] => Double
                         ): Option[Double] = {
    val courseScores = getCourseScores(courseId).map(_.score)
    if (courseScores.nonEmpty) Some(analyzer(courseScores)) else None
  }

  // 7. 教师管理模块函数
  def addTeacher(name: String, department: String, title: String): String = {
    val id = generateId("T")
    teachers(id) = Teacher(id, name, department, title)
    id
  }

  def getTeacher(teacherId: String): Option[Teacher] = teachers.get(teacherId)

  // 递归函数：计算教师工作量（学分总和）
  def calculateTeacherWorkload(teacherId: String): Double = {
    val teacherCourses = getCoursesByTeacher(teacherId)
    if (teacherCourses.isEmpty) 0.0
    else teacherCourses.head.credit + calculateTeacherWorkload(teacherId, teacherCourses.tail)
  }

  // 辅助递归函数
  private def calculateTeacherWorkload(teacherId: String, remainingCourses: List[Course]): Double = {
    if (remainingCourses.isEmpty) 0.0
    else remainingCourses.head.credit + calculateTeacherWorkload(teacherId, remainingCourses.tail)
  }
  // 8. 系统初始化与测试
  println("===== 校园信息管理系统 ======")

  // 添加教师
  val teacherId1 = addTeacher("张教授", "计算机系", "教授")
  val teacherId2 = addTeacher("李老师", "数学系", "讲师")

  // 添加课程
  val courseId1 = addCourse("Scala编程", teacherId1, 3.0, 50)
  val courseId2 = addCourse("数据结构", teacherId1, 4.0, 60)
  val courseId3 = addCourse("高等数学", teacherId2, 5.0, 100)

  // 添加学生
  val classNames = List("计科1班", "计科2班", "数学1班")
  val studentIds = for (i <- 1 to 15) yield {
    val className = classNames(i % 3)
    val gender = if (i % 2 == 0) "男" else "女"
    addStudent(s"学生$i", className, 18 + i % 3, gender)
  }

  // 添加成绩
  val examDate = "2025-12-20"
  studentIds.take(10).foreach { studentId =>
    addScore(studentId, courseId1, 60 + Random.nextDouble() * 40, examDate)
  }

  studentIds.take(8).foreach { studentId =>
    addScore(studentId, courseId2, 65 + Random.nextDouble() * 35, examDate)
  }
  // 9. 系统功能演示
  println(s"\n系统初始化完成: ${students.size}名学生，${courses.size}门课程，${teachers.size}名教师")

  // 查询班级学生
  val className = "计科1班"
  val classStudents = getStudentsByClass(className)
  println(s"\n$className 共有 ${classStudents.size} 名学生: ")
  classStudents.foreach(s => println(s"${s.id}: ${s.name} (${s.age}岁) "))

  // 统计性别比例
  val maleCount = countStudentsByGender("男")
  val femaleCount = countStudentsByGender("女")
  println(s"学生性别比例: 男 $maleCount 人，女 $femaleCount 人")

  // 分析课程成绩
  val course1Avg = analyzeCourseScores(courseId1, scores => scores.sum / scores.size)
  val course1Max = analyzeCourseScores(courseId1, scores => scores.max)
  val course1Min = analyzeCourseScores(courseId1, scores => scores.min)

  getCourse(courseId1).foreach { course =>
    println(s"\n${course.name} 成绩统计: ")
    printf("平均分: %.1f\n", course1Avg.getOrElse(0.0))
    printf("最高分: %.1f\n", course1Max.getOrElse(0.0))
    printf("最低分: %.1f\n", course1Min.getOrElse(0.0))
  }

  // 计算教师工作量
  getTeacher(teacherId1).foreach { teacher =>
    val workload = calculateTeacherWorkload(teacherId1)
    println(s"\n${teacher.name} 的工作量(总学分): $workload")
  }
}
